﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Text;
using System.Timers;
using System.Threading;
using System.Collections;

namespace PingRT
{
    class Pinger
    {
        public static ArrayList ConfigNodeOption = ConfigINI.GetIniValue("option");
        public static ArrayList ConfigNodeHost = ConfigINI.GetIniValue("host");
        System.Timers.Timer PingTimer = new System.Timers.Timer(1000);
        System.Timers.Timer ProgramTimer = new System.Timers.Timer(1000);

        public Pinger()
        {           
            ReportAvailability();
            NetworkStatus.AvailabilityChanged += new NetworkStatusChangedHandler(DoAvailabilityChanged);
        }

        public void ProgramStart(object source, ElapsedEventArgs e)
        {

            if (ConfigNodeOption[0].ToString()=="true")
            {
                PingTimer.Start();
                StringBuilder NotifyText = new StringBuilder();
                NotifyText.Append("PingRT\n");
                NotifyText.Append("目标："+ConfigNodeHost[0]+"\n");
                NotifyText.Append("阈值：" + ConfigNodeHost[1] + "MS\n");
                NotifyText.Append("发送：" + FlowRate.GetSendByte().ToString() + "KB/s\n");
                NotifyText.Append("接收：" + FlowRate.GetRecievedByte().ToString() + "KB/s");  
                NotifyEvent.SetNotifyText(NotifyText.ToString());
            }
            else
            {
                PingTimer.Stop();
                Que.DelAll();
                NotifyEvent.IconEvent.Icon = Properties.Resources.network512_white;
            }
            //new Policy();
        }

        public  void PingAsync(string args)
        {
            if (args.Length == 0)
                throw new ArgumentException("Ping needs a host or IP Address.");
            string who = args;
            AutoResetEvent waiter = new AutoResetEvent(false);
            Ping pingSender = new Ping();
            pingSender.PingCompleted += new PingCompletedEventHandler(PingCompletedCallback);
            string data = "This is just a test";
            byte[] buffer = Encoding.ASCII.GetBytes(data);
            int timeout = 12000;
            PingOptions options = new PingOptions(64, true);
            pingSender.SendAsync(who, timeout, buffer, options, waiter);
            waiter.WaitOne();
        }

        private  void PingCompletedCallback(object sender, PingCompletedEventArgs e)
        {
            if (e.Cancelled)
            {
                Console.WriteLine("Ping canceled.");

                ((AutoResetEvent)e.UserState).Set();
            }
            if (e.Error != null)
                ((AutoResetEvent)e.UserState).Set();
            PingReply reply = e.Reply;
            if (reply.Status == IPStatus.Success)
            {
                if (Convert.ToUInt16(reply.RoundtripTime) >= Convert.ToUInt16(Pinger.ConfigNodeHost[1]))
                    Que.AddValue(0);
                else
                    Que.AddValue(reply.RoundtripTime);
            }
            else
                Que.AddValue(0);         
            ((AutoResetEvent)e.UserState).Set();
        }

        public void TargetHost(object source, ElapsedEventArgs e)
        {
            PingTimer.Interval = Convert.ToUInt16(Pinger.ConfigNodeOption[1]) * 1000;
            string host= Pinger.ConfigNodeHost[0].ToString();
            if (Utils.IsDomain(Pinger.ConfigNodeHost[0].ToString()))
            {
                IPHostEntry hostinfo = Dns.GetHostByName(ConfigNodeHost[0].ToString());
                IPAddress ip = hostinfo.AddressList[0];
                host = ip.ToString();
            }
            PingAsync(host);
            //PingAsync(Pinger.ConfigNodeHost[0].ToString());
            
        }

        private void DoAvailabilityChanged(object sender, NetworkStatusChangedArgs e)
        {
            ReportAvailability();
        }

        private  void ReportAvailability()
        {
            if (NetworkStatus.IsAvailable)
            {
                System.Diagnostics.Debug.WriteLine("网络可用");
                PingTimer.Elapsed += new ElapsedEventHandler(TargetHost);
                System.Timers.Timer ProgramTimer = new System.Timers.Timer(1000);
                ProgramTimer.Elapsed += new ElapsedEventHandler(ProgramStart);
                ProgramTimer.Start();
            }
            else
            {
                System.Diagnostics.Debug.WriteLine("网络不可用");
                PingTimer.Stop();
                ProgramTimer.Stop();
                Que.DelAll();
            }
        }

    }
}
